/*
 *  $Id: Activatable.cs 508 2008-11-26 11:08:10Z thenn.erannor $
 *	This file is a part of Ragima CCG.
 *	(C) 2008 Ragima development group.
 *
 *	Licensed under the terms of the GNU GPL License version 2.
 *
 */

using System;
using System.Collections.Generic;

namespace Ragima {
    /// <summary>
    /// Абстрактный активируемый эффект: частично установка проводится методом Activate,
    /// вызываемым только у одного эффекта данного типа.
    /// </summary>
    public abstract class ActivatableAffect: Affect {
        private bool _activated;

        public ActivatableAffect(): base() {
            _activated = false;
        }

        public bool Activated {
            get { return _activated; }
        }

        public override void SetAffect() {
            base.SetAffect();
            LocalSummary.Activatables.Add(this);
        }
        public override void ResetAffect() {
            base.ResetAffect();
            LocalSummary.Activatables.Remove(this);
        }

        public virtual void Activate() {
            _activated = true;
        }
        public virtual void Deactivate() {
            _activated = false;
        }
    }

    /// <summary>
    /// Список активируемых эффектов, поддерживающий активацию у одного эффекта.
    /// </summary>
    public sealed class ActivatableAffectList {
        private List<ActivatableAffect> _list;

        public ActivatableAffectList() {
            _list = new List<ActivatableAffect>();
        }

        public bool Empty {
            get { return _list.Count == 0; }
        }

        public void Add(ActivatableAffect affect) {
            _list.Add(affect);
            if (_list.Count == 1) affect.Activate();
        }

        public void Remove(ActivatableAffect affect) {
            if (!_list.Contains(affect)) return;
            _list.Remove(affect);
            if (affect.Activated) {
                affect.Deactivate();
                if (_list.Count > 0) _list[0].Activate();
            }
        }
    }

    /// <summary>
    /// Словарь активируемых эффектов, группирующий эффекты по их типам.
    /// </summary>
    public sealed class ActivatableAffectDictionary {
        private Dictionary<Type, ActivatableAffectList> _dict;

        public ActivatableAffectDictionary() {
            _dict = new Dictionary<Type,ActivatableAffectList>();
        }

        public void Add(ActivatableAffect affect) {
            Type key = affect.GetType();
            ActivatableAffectList list;
            if (_dict.ContainsKey(key))
                list = _dict[key];
            else {
                list = new ActivatableAffectList();
                _dict.Add(key, list);
            }
            list.Add(affect);
        }

        public void Remove(ActivatableAffect affect) {
            Type key = affect.GetType();
            if (!_dict.ContainsKey(key)) return;
            ActivatableAffectList list = _dict[key];
            list.Remove(affect);
            if (list.Empty) _dict.Remove(key);
        }
    }
}